#ifndef _lock_h_
#define _lock_h_

// lock.h
//
//  Thread synchronization routines, or null objects for
//  platforms that do not support (or do not need) this
//  functionality.

// Decide which implementation to use
// Defining AP_NOTHREADS will use the default implementation in
// applications where threading isn't an issue.
namespace simple{

    #if !defined(AP_NOTHREADS) && defined(WIN32)
    #include <win32/lock.h>
    #elif !defined(AP_NOTHREADS) && defined(HasPTHREADS)
    #include <unix/lock.h>
    #else

    //
    // Lock
    //
    // Lock is a simple wrapper around a synchronization object
    // that only allows a single thread access to a resource at a
    // time. The default version does nothing and is suitable for
    // platforms that do not support threading, or applications that
    // do not need it.

    class Lock
    {
    public:
        Lock  ()     {}
        ~Lock ()     {}

        bool lock   () { return true;}     // Get the lock
        bool unlock () { return true;}     // Release the lock
    };

    #endif

    //
    // Locker
    //
    // Locker is a generic version of RAII (resource acquisition is
    // initialization).
    //
    //   1) Create a global lock that you will use for your resource
    //         ex:  Lock coutLock;
    //   2) Use an instance of Locker to manage this resource
    //         ex:
    //         {
    //           Locker lock(coutLock);
    //           std::cout << "Locked access to std::cout" << std::endl;
    //         }

    class Locker
    {
    public:
        Locker (Lock& lock) : lock_ (lock)  { lock_.lock();}
        ~Locker () { lock_.unlock();}

    private:
        Lock& lock_;

        // Prohibit copy and assignment
        Locker            (const Locker& src);
        Locker& operator= (const Locker& src);
    };

}

#endif // _lock_h_
